<template >
  <div class="markdown-body" v-html="renderedMarkdown"></div>
</template>

<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { marked } from 'marked'
import Clipboard from 'clipboard'
import hljs from 'highlight.js/lib/common'
import 'highlight.js/styles/atom-one-dark.css'

const props = defineProps<{
  markdownText: string
}>()

const message = useMessage()

const renderedMarkdown = ref('')

// 使用 watch 监听 props.markdownText 的变化
watch(
  () => props.markdownText,
  (newMarkdown) => {
    renderedMarkdown.value = renderMarkdown(newMarkdown)
  }
)
/**
 * 使用 marked 解析 Markdown
 * @param markdown 解析的文本
 */
const renderMarkdown = (markdown: string): string => {
  const renderer = new marked.Renderer()
  // 自定义代码块的渲染逻辑
  renderer.code = ({ text, lang }: marked.Tokens.Code): string => {
    const language = hljs.getLanguage(lang) ? lang : 'plaintext'
    const highlighted = hljs.highlight(text, { language }).value

    // 生成唯一标识
    const codeIndex = parseInt(Date.now() + '') + Math.floor(Math.random() * 10000000)

    // 添加复制按钮
    const copyButton = `
        <div class="codeblockheader">
          <div>${language}</div>
          <div id="copy-btn" data-clipboard-action="copy" data-clipboard-target="#copy${codeIndex}">复制</div>
        </div>
      `

    // 生成代码块和隐藏的 textarea 用于复制
    return `${copyButton}<pre class="hljs"><code>${highlighted}</code></pre>
      <textarea style="position: absolute; top: -9999px; left: -9999px; z-index: -9999;" id="copy${codeIndex}">${text.replace(
      /<\/textarea>/g,
      '&lt;/textarea>'
    )}</textarea>`
  }
  return marked(markdown, { renderer }) as string
}

onMounted(() => {
  renderedMarkdown.value = renderMarkdown(props.markdownText)
  // 只在第一次渲染时绑定事件监听器
  if (!window.clipboardInitialized) {
    const clipboard = new Clipboard('#copy-btn')
    clipboard.on('success', (e) => {
      message.success('  复制成功')
    })
    clipboard.on('error', (e) => {
      message.error('  复制失败')
      clipboard.destroy()
    })
    window.clipboardInitialized = true
  }
})

onUnmounted(() => {
  // 清理事件监听器
  //   if (window.clipboardInitialized) {
  //     window.clipboardInitialized = false
  //     // 假设 clipboard 实例可以被全局访问
  //     clipboard.destroy()
  //   }
})
</script>

<style scoped lang="scss">
:deep(.codeblockheader) {
  display: flex;
  justify-content: space-between;
  line-height: 20px;
  padding: 5px 10px;
  background: rgb(80, 81, 83);
  border-radius: 5px 5px 0 0;
  color: #fff;
  cursor: pointer;
}

:deep(pre) {
  margin: 0; /* 移除默认的外边距 */
  padding: 5px 10px; /* 移除默认的内边距 */
  overflow-x: auto; /* 确保长代码可以滚动 */
  white-space: pre-wrap; /* 保留换行但允许自动换行 */
  word-wrap: break-word; /* 允许长单词换行 */
}
</style>

<style>
.markdown-body table {
  width: 100%;
  border-collapse: collapse;
  /* 让表格边框合并 */
  box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.2);
  /* 添加表格阴影 */
  margin: 10px 0;
}

.markdown-body th,
.markdown-body td {
  border: 1px solid #ddd;
  /* 添加边框 */
  padding: 8px;
  text-align: left;
}

.markdown-body th {
  background-color: #f4f4f4;
  /* 表头背景色 */
  font-weight: bold;
}
</style>

